package zust.se.delicious.dao.impl;

import java.sql.SQLException;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import zust.se.delicious.dao.FollowDao;
import zust.se.delicious.domain.Follow;
import zust.se.delicious.domain.User;

public class FollowDaoImpl extends HibernateDaoSupport implements FollowDao {

	@Override
	public Follow get(Integer id) {
		return getHibernateTemplate().get(Follow.class, id);
	}

	@Override
	public Integer save(Follow Follow) {
		return (Integer) getHibernateTemplate().save(Follow);
	}

	@Override
	public void update(Follow Follow) {
		getHibernateTemplate().update(Follow);

	}

	@Override
	public void delete(Follow Follow) {
		getHibernateTemplate().delete(Follow);

	}

	@Override
	public void delete(Integer id) {
		getHibernateTemplate().delete(get(id));

	}

	@Override
	public List<Follow> findAll() {
		return (List<Follow>) getHibernateTemplate().find("from Follow");
	}

	@Override
	public List<Follow> findFollowerByUser_id(Integer id) {
		User user = new User(id);
		return (List<Follow>) getHibernateTemplate().find("from Follow p where p.following = ?", user);
	}

	@Override
	public List<Follow> findFollowingByUser_id(Integer id) {
		User user = new User(id);
		return (List<Follow>) getHibernateTemplate().find("from Follow p where p.follower = ?", user);
	}

	@Override
	public Long countFollow(final Integer uid) {
		return getHibernateTemplate().execute(new HibernateCallback() {
			@Override
			public Object doInHibernate(Session session) throws HibernateException, SQLException {
				String hql = "select count(*) from Follow where following=:following";
				return session.createQuery(hql).setEntity("following", new User(uid)).iterate().next();
			}

		});
	}

	@Override
	public Long countFollowing(final Integer uid) {
		return getHibernateTemplate().execute(new HibernateCallback() {
			@Override
			public Object doInHibernate(Session session) throws HibernateException, SQLException {
				String hql = "select count(*) from Follow where follower=:follower";
				return session.createQuery(hql).setEntity("follower", new User(uid)).iterate().next();
			}

		});
	}

	@Override
	public boolean isFollow(Follow follow) {
		List<Follow> list = (List<Follow>) getHibernateTemplate().find("from Follow p where p.follower = ? and p.following = ?",
				follow.getFollower(), follow.getFollowing());
		return (list != null && list.size() > 0) ? true : false;
	}

	@SuppressWarnings("unchecked")
	@Override
	public boolean delete(final Integer uid, final Integer fid) {

		int row = getHibernateTemplate().execute(new HibernateCallback() {
			@Override
			public Object doInHibernate(Session session) throws HibernateException, SQLException {
				String hql = "delete from Follow where follower=:follower and following=:following";
				return session.createQuery(hql).setEntity("follower", new User(uid)).setEntity("following", new User(fid)).executeUpdate();
			}
		});
		System.out.println("row=" + row);
		return row>0;
	}
	
	@SuppressWarnings("unchecked")
	public List<User> getFollowingList(final int uid, final int page, final int size) {
		return getHibernateTemplate().executeFind(new HibernateCallback() {
			@Override
			public Object doInHibernate(Session session) throws HibernateException, SQLException {
				String hql = "select f.following from Follow f where f.follower=:user";
				return session.createQuery(hql).setEntity("user", new User(uid)).setFirstResult((page - 1) * size).setMaxResults(size).list();
			}

		});
	}

	@SuppressWarnings("unchecked")
	public List<User> getFollowerList(final int uid, final int page, final int size) {
		return getHibernateTemplate().executeFind(new HibernateCallback() {
			@Override
			public Object doInHibernate(Session session) throws HibernateException, SQLException {
				String hql = "select f.follower from Follow f where f.following=:user";
				return session.createQuery(hql).setEntity("user", new User(uid)).setFirstResult((page - 1) * size).setMaxResults(size).list();
			}

		});
	}

}
